package main

import (
	"errors"
	"fmt"
	"math/rand"
	"strconv"
)

type OrderState uint8

const (
	Created OrderState = iota + 1
	Canceled
	Payed
	Delivered
	Received
	Returned
	Commented
	Closed
)

type OrderContext struct {
	orderId string
	state   OrderState
}

type OrderHandler interface {
	Handle(ctx *OrderContext, listener OrderStatusUpdateListener) error
}

type PlaceOrderHandler struct {
	userId int
}

func (p *PlaceOrderHandler) Handle(ctx *OrderContext, listener OrderStatusUpdateListener) error {
	fmt.Printf("userid = %d place order\n", p.userId)
	ctx.state = Created
	ctx.orderId = strconv.Itoa(rand.Intn(1000))

	return nil
}

type PayedHandler struct {
}

func (p *PayedHandler) Handle(ctx *OrderContext, listener OrderStatusUpdateListener) error {
	if ctx == nil || ctx.state != Created {
		return errors.New("state is illegal")
	}
	ctx.state = Payed
	listener.OnChange(*ctx, Created, Payed)
	return nil
}

type OrderStatusUpdateListener interface {
	OnChange(ctx OrderContext, before OrderState, after OrderState)
}
